package com.ra.statis;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.annotation.Resource;

import org.hibernate.jdbc.ReturningWork;
import org.springframework.stereotype.Service;

import com.googlecode.cswish.struts.spring.GenericService;
import com.ra.landlord.LandlordUser;

@Service
public class LandlordFunctionService {

	@Resource
	private GenericService genericService;
	
	/**
	 * Scheduled, 房东数据评估, 每晚执行
	 */
	public void analyse() {
		genericService.doReturningWork(new ReturningWork<Boolean>() {

			@Override
			public Boolean execute(Connection connection) throws SQLException {
				String sql = "select u.user_id, p.path, count(1) as pathCount from ra_performancelog p left join ra_landlorduser u on p.userId = u.loginUser_id"
							+ " where p.userId is not null and u.user_id <> 0" 
							+ " and (p.path = ? or p.path = ? or p.path = ? or p.path = ? or p.path = ? or p.path = ?"
							+ "  or p.path = ? or p.path = ? or p.path = ? or p.path = ? or p.path = ?) group by u.user_id, p.path order by u.user_id";
				try (PreparedStatement stmt = connection.prepareStatement(sql)) {
					int index = 0;
					stmt.setString(++index, LandlordFunction.PATH_RENTOUT);
					stmt.setString(++index, LandlordFunction.PATH_RENTOUT2);
					stmt.setString(++index, LandlordFunction.PATH_RENTOUT3);
					stmt.setString(++index, LandlordFunction.PATH_COLLECTRENT);
					stmt.setString(++index, LandlordFunction.PATH_COLLECTRENT2);
					stmt.setString(++index, LandlordFunction.PATH_COLLECTRENT3);
					stmt.setString(++index, LandlordFunction.PATH_PAYRENT);
					stmt.setString(++index, LandlordFunction.PATH_PAYRENT2);
					stmt.setString(++index, LandlordFunction.PATH_REMINDER);
					stmt.setString(++index, LandlordFunction.PATH_PUBLISH);
					stmt.setString(++index, LandlordFunction.PATH_QRCODE);
					
					LandlordFunction landlordFunction = null;
					int rentout2 = 0;
					int rentout3 = 0;
					int collectRent2 = 0;
					int collectRent3 = 0;
					int payrent2 = 0;
					try (ResultSet rs = stmt.executeQuery()) {
						while (rs.next()) {
							Integer landlordId = rs.getInt("user_id");
							String path = rs.getString("path");
							Integer count = rs.getInt("pathCount");
							
							if (landlordFunction == null || !landlordFunction.getLandlordUser().getId().equals(landlordId)) {
								// update the previous record
								if (landlordFunction != null) {
									boolean isFirstCreation = (landlordFunction.getId() == null);
									increaseCount(landlordFunction, rentout2, rentout3, collectRent2, collectRent3, payrent2);
									landlordFunction = genericService.merge(landlordFunction);
									rentout2 = 0;
									rentout3 = 0;
									collectRent2 = 0;
									collectRent3 = 0;
									payrent2 = 0;
									
									if (isFirstCreation) {
										LandlordEstimation landlordEstimation = new LandlordEstimation();
										landlordEstimation.setLandlordUser(landlordFunction.getLandlordUser());
										LandlordEstimation dbLandlordEstimation = genericService.searchAll(landlordEstimation).getData(0);
										if (dbLandlordEstimation != null) {
											dbLandlordEstimation.setLandlordFunction(landlordFunction);
											genericService.merge(dbLandlordEstimation);
										}
									}
								}
								
								// find the new landlordFunction
								landlordFunction = new LandlordFunction();
								LandlordUser landlordUser = genericService.load(LandlordUser.class, landlordId);
								if (landlordUser == null) {
									// it's invalid landlord user id
									continue;
								}
								
								landlordFunction.setLandlordUser(landlordUser);
								LandlordFunction dbLandlordFunction = genericService.searchAll(landlordFunction).getData(0);
								if (dbLandlordFunction != null) {
									landlordFunction = dbLandlordFunction;
								}
							}
							
							if (LandlordFunction.PATH_RENTOUT.equals(path)) {
								landlordFunction.setRentOut(count);
							} else if (LandlordFunction.PATH_RENTOUT2.equals(path)) {
								rentout2 = count;
							} else if (LandlordFunction.PATH_RENTOUT3.equals(path)) {
								rentout3 = count;
							} else if (LandlordFunction.PATH_COLLECTRENT.equals(path)) {
								landlordFunction.setCollectRent(count);
							} else if (LandlordFunction.PATH_COLLECTRENT2.equals(path)) {
								collectRent2 = count;
							} else if (LandlordFunction.PATH_COLLECTRENT3.equals(path)) {
								collectRent3 = count;
							} else if (LandlordFunction.PATH_PAYRENT.equals(path)) {
								landlordFunction.setPayRent(count);
							} else if (LandlordFunction.PATH_PAYRENT2.equals(path)) {
								payrent2 = count;
							} else if (LandlordFunction.PATH_REMINDER.equals(path)) {
								landlordFunction.setReminder(count);
							} else if (LandlordFunction.PATH_PUBLISH.equals(path)) {
								landlordFunction.setPublish(count);
							} else if (LandlordFunction.PATH_QRCODE.equals(path)) {
								landlordFunction.setQrCode(count);
							}
						}
					}
					
					if (landlordFunction != null) {
						increaseCount(landlordFunction, rentout2, rentout3, collectRent2, collectRent3, payrent2);
						genericService.merge(landlordFunction);
					}
				}
				return Boolean.TRUE;
			}

			private void increaseCount(LandlordFunction landlordFunction, int rentout2, int rentout3, int collectRent2, int collectRent3, int payrent2) {
				if (rentout2 > 0 || rentout3 > 0) {
					rentout2 += rentout3;
					if (landlordFunction.getRentOut() == null) {
						landlordFunction.setRentOut(rentout2);
					} else {
						landlordFunction.setRentOut(landlordFunction.getRentOut() + rentout2);
					}
				}
				if (collectRent2 > 0 || collectRent3 > 0) {
					collectRent2 += collectRent3;
					if (landlordFunction.getCollectRent() == null) {
						landlordFunction.setCollectRent(collectRent2);
					} else {
						landlordFunction.setCollectRent(landlordFunction.getCollectRent() + collectRent2);
					}
				}
				if (payrent2 > 0) {
					if (landlordFunction.getPayRent() == null) {
						landlordFunction.setPayRent(payrent2);
					} else {
						landlordFunction.setPayRent(landlordFunction.getPayRent() + payrent2);
					}
				}
			}
		});
	}
}